﻿#region

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Radovici.SharedLibrary;

#endregion

namespace Radovici.Ctrls.Panels
{
    public class MacPanel : AnimatingPanelBase //Panel
    {
        #region Private fields

        private Point _fillerOffset;
        private Point _mousePosition;

        #endregion

        private readonly Rectangle _filler = new Rectangle {Fill = new SolidColorBrush(Colors.Transparent)};

        public MacPanel()
        {
            Loaded += OnLoaded;
            var root = Application.Current.RootVisual as FrameworkElement;
            if (root != null)
            {
                root.SizeChanged += OnRootSizeChanged;
            }
            _filler.MouseMove += OnFillerMouseMove;
            //Application.Current.RootVisual.MouseMove += new MouseEventHandler(OnMouseMove);
        }

        private void OnFillerMouseMove(object sender, MouseEventArgs e)
        {
            _mousePosition = e.GetPosition(this);
            InvalidateMeasure();
        }

        private void OnRootSizeChanged(object sender, SizeChangedEventArgs e)
        {
            _filler.Width = e.NewSize.Width;
            _filler.Height = e.NewSize.Height;
            InvalidateMeasure();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (!Children.Contains(_filler))
            {
                Children.Insert(0, _filler);
            }
        }

        private void OnMouseMove(object sender, MouseEventArgs e)
        {
            //Debug.WriteLine("MacPanel:OnMouseOver");
            _mousePosition = e.GetPosition(this);
            //if (_mousePosition.X > 0 && _mousePosition.X < this.DesiredSize.Width && _mousePosition.Y > 0 && _mousePosition.Y < this.DesiredSize.Height)
            //{
            InvalidateMeasure();
            //}            
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (FrameworkElement child in Children)
            {
                if (child == _filler)
                {
                    child.Measure(availableSize);
                    continue;
                }
                double closenessPercent = double.NaN;
                GeneralTransform gt = child.TransformToVisual(this);
                Point offset = gt.Transform(new Point());
                double controlLeft = offset.X + child.DesiredSize.Width/2.0;
                double closenessLeft = Math.Abs(_mousePosition.X - controlLeft);
                double closenessLeftPercent = (availableSize.Width - closenessLeft)/availableSize.Width;
                double controlTop = offset.Y + child.DesiredSize.Height/2.0;
                double closenessTop = Math.Abs(_mousePosition.Y - controlTop);
                double closenessTopPercent = (availableSize.Height - closenessTop)/availableSize.Height;
                closenessPercent = (closenessLeftPercent + closenessTopPercent)/2.0;
                child.Measure(new Size(availableSize.Width,
                                       availableSize.Height*
                                       Math.Max(double.IsNaN(closenessPercent) ? 0 : closenessPercent, 0.75)));
            }
            return new Size(double.IsInfinity(availableSize.Width) ? 0 : availableSize.Width,
                            double.IsInfinity(availableSize.Height) ? 0 : availableSize.Height);
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            GeneralTransform gt = Application.Current.RootVisual.TransformToVisual(this);
            _fillerOffset = gt.Transform(new Point());
            double width = 0;
            double height = finalSize.Height;
            foreach (FrameworkElement child in Children)
            {
                if (child == _filler)
                {
                    var fillerRect = new Rect(_fillerOffset.X, 0, child.DesiredSize.Width, child.DesiredSize.Height);
                    child.Arrange(fillerRect);
                    continue;
                }
                var finalRect = new Rect(width, finalSize.Height - child.DesiredSize.Height, child.DesiredSize.Width,
                                         child.DesiredSize.Height);
                base.SetElementLocation(child, finalRect);
                width += finalRect.Width;
                height = Math.Max(height, finalRect.Height);
            }
            return new Size(width, height);
        }
    }
}